package com.wx.service.impl;

import com.google.common.collect.Lists;
import com.wx.common.SecurityUser;
import com.wx.constants.Constants;
import com.wx.domain.dto.AuthUserDto;
import com.wx.domain.dto.RoleDto;
import com.wx.domain.dto.SysMenuDto;
import com.wx.domain.dto.UpdatePwdDto;
import com.wx.entity.SysMenu;
import com.wx.entity.SysRole;
import com.wx.entity.SysUser;
import com.wx.entity.SysUserRole;
import com.wx.enums.UserStatusEnum;
import com.wx.exception.BusinessException;
import com.wx.mapper.SysUserMapper;
import com.wx.properties.OssProperties;
import com.wx.service.SysRoleMenuService;
import com.wx.service.SysUserRoleService;
import com.wx.service.SysUserService;
import com.wx.utils.SnowFlakeUtil;
import com.wx.utils.TreeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>Title:	  UserServiceImpl <br/> </p>
 * <p>Description TODO <br/> </p>
 * <p>Company:    医百科技有限公司  <br/> </p>
 *
 * @Author <a href="xinglinglove1029@163.com"/>杨文生</a>  <br/>
 * @Date 2017/5/15 13:50
 */
@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUser> implements SysUserService {

	@Resource
	private SysUserMapper userMapper;

	@Resource
	private SysUserRoleService userRoleService;

	@Resource
	private SysRoleMenuService sysRoleMenuService;

	@Resource
	private OssProperties ossProperties;


	private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

	@Override
	public SysUser selectUserByUserName(String username) {
		return userMapper.loadUserByUsername(username);
	}

	@Override
	public AuthUserDto getAuthUserInfo(String userId) {
		SysUser user = userMapper.selectByPrimaryKey(userId);
		AuthUserDto authUserDto = new AuthUserDto();
		BeanUtils.copyProperties(user, authUserDto);
		authUserDto.setPhone(user.getMobile());
		authUserDto.setAvatar(ossProperties.getUrl()+user.getAvatar());
		SysUserRole query = new SysUserRole();
		query.setUserId(user.getId());
		List<RoleDto> roleList = userRoleService.queryOwnRoles(query);
		List<String> roles = roleList.stream().map(RoleDto::getRoleCode).collect(Collectors.toList());
		authUserDto.setUserId(user.getId());
		authUserDto.setRoles(roles);
		List<String> roleIdList = roleList.stream().map(RoleDto::getId).collect(Collectors.toList());
		// 查询有权限的菜单
		List<SysMenu> menuList = sysRoleMenuService.getMenuByRoleIds(roleIdList);
		List<SysMenuDto> menuDtoList = Lists.newArrayList();
		for (SysMenu sysMenu : menuList) {
			SysMenuDto sysMenuDto = new SysMenuDto();
			sysMenuDto.setMenuCode(sysMenu.getMenuCode());
			sysMenuDto.setId(sysMenu.getId());
			sysMenuDto.setMenuName(sysMenu.getMenuName());
			sysMenuDto.setUrl(sysMenu.getUrl());
			sysMenuDto.setIcon(sysMenu.getIcon());
			sysMenuDto.setParentId(sysMenu.getPid());
			menuDtoList.add(sysMenuDto);
		}
		List<SysMenuDto> resultList = TreeUtil.bulid(menuDtoList, Constants.Sys.ROOT);
		authUserDto.setMenuList(resultList);
		return authUserDto;
	}

	@Override
	public List<SysUser> queryListPage(SysUser user) {
		return userMapper.queryListPage(user);
	}

	@Override
	public int deleteUserById(String id, SecurityUser authUserDto) {
		String currentUserId = authUserDto.getUserId();
		if(currentUserId.equals(id)){
			throw new BusinessException("自己不能删除自己");
		}
		SysUser queryUser = new SysUser();
		queryUser.setId(id);
		queryUser.setDelFlag(Constants.DELETE_NO);
		SysUser user = userMapper.selectOne(queryUser);
		if(Objects.isNull(user)) {
			throw new BusinessException("用户信息不存在");
		}
		// 判断用户是否和角色还存在绑定关系
		List<SysRole> bindRoleListByUserId = userRoleService.getBindRoleListByUserId(id);
		if(bindRoleListByUserId.size() > 0){
			throw new BusinessException("该用户还与角色存在绑定关系，不能删除");
		}
		queryUser.setDelFlag(Constants.DELETE_YES);
		queryUser.setUpdater(authUserDto.getUsername());
		queryUser.setUpdateBy(authUserDto.getUserId());
		queryUser.setUpdateDate(new Date());
		return userMapper.updateByPrimaryKeySelective(queryUser);
	}

	@Override
	public int disableUserById(String id, SecurityUser authUserDto) {
		String currentUserId = authUserDto.getUserId();
		if(currentUserId.equals(id)){
			throw new BusinessException("自己不能禁用自己");
		}
		SysUser queryUser = new SysUser();
		queryUser.setId(id);
		queryUser.setDelFlag(Constants.DELETE_NO);
		SysUser user = userMapper.selectOne(queryUser);
		if(Objects.isNull(user)) {
			throw new BusinessException("用户信息不存在");
		}
		if(UserStatusEnum.ENABLE.getKey() != user.getStatus()){
			throw new BusinessException("不是启用状态的不能禁用");
		}
		queryUser.setStatus(UserStatusEnum.DISABLE.getKey());
		queryUser.setUpdater(authUserDto.getUsername());
		queryUser.setUpdateBy(authUserDto.getUserId());
		queryUser.setUpdateDate(new Date());
		return userMapper.updateByPrimaryKeySelective(queryUser);
	}

	@Override
	public int enableUserById(String id, SecurityUser authUserDto) {
		SysUser queryUser = new SysUser();
		queryUser.setId(id);
		queryUser.setDelFlag(Constants.DELETE_NO);
		SysUser user = userMapper.selectOne(queryUser);
		if(Objects.isNull(user)) {
			throw new BusinessException("用户信息不存在");
		}
		if(UserStatusEnum.DISABLE.getKey() != user.getStatus()){
			throw new BusinessException("不是禁用状态的不能启用");
		}
		queryUser.setStatus(UserStatusEnum.ENABLE.getKey());
		queryUser.setUpdater(authUserDto.getUsername());
		queryUser.setUpdateBy(authUserDto.getUserId());
		queryUser.setUpdateDate(new Date());
		return userMapper.updateByPrimaryKeySelective(queryUser);
	}

	@Override
	public int modifyUser(SysUser user, SecurityUser securityUser) {
		if(StringUtils.isEmpty(user.getId())) {
			throw new BusinessException("用户编号不能为空！");
		}
		SysUser queryUser = new SysUser();
		queryUser.setId(user.getId());
		queryUser.setDelFlag(Constants.DELETE_NO);
		SysUser us = userMapper.selectOne(queryUser);
		if(Objects.isNull(us)) {
			throw new BusinessException("用户信息不存在");
		}
		user.setUpdateDate(new Date());
		return userMapper.updateByPrimaryKeySelective(user);
	}

	@Override
	public int saveUserInfo(SysUser user, SecurityUser securityUser) {
		// 校验用户信息是否已经存在
		SysUser queryUser = new SysUser();
		queryUser.setUserName(user.getUserName());
		queryUser.setDelFlag(Constants.DELETE_NO);
		SysUser us = userMapper.selectOne(queryUser);
		if(!Objects.isNull(us)) {
			throw new BusinessException("用户信息已经存在，不能重复新增");
		}
		String hash = encoder.encode(user.getPassword());
		user.setPassword(hash);
		user.setId(SnowFlakeUtil.getStringId());
		return userMapper.insertSelective(user);
	}

	@Override
	public int modifyPassword(UpdatePwdDto user, SecurityUser authUserDto) {
		if (StringUtils.isEmpty(user.getUserId())) {
			throw new BusinessException("用户不能为空！");
		}
		if (user.getOldPassword().equals(user.getPassword())) {
			throw new BusinessException("新密码不能与原密码相同");
		}
		SysUser queryUser = new SysUser();
		queryUser.setId(user.getUserId());
		queryUser.setDelFlag(Constants.DELETE_NO);
		SysUser us = userMapper.selectOne(queryUser);
		if (Objects.isNull(us)) {
			throw new BusinessException("用户信息不存在");
		}
		if (!encoder.matches(user.getOldPassword(), us.getPassword())) {
			throw new BusinessException("旧密码不正确");
		}
		String hash = encoder.encode(user.getPassword());
		queryUser.setPassword(hash);
		queryUser.setUpdater(authUserDto.getUsername());
		queryUser.setUpdateBy(authUserDto.getUserId());
		queryUser.setUpdateDate(new Date());
		return userMapper.updateByPrimaryKeySelective(queryUser);
	}

	@Override
	public int resetPassword(UpdatePwdDto user, SecurityUser securityUser) {
		if (org.apache.commons.lang3.StringUtils.isEmpty(user.getUserId())) {
			throw new BusinessException("用户编号不能为空！");
		}
		SysUser queryUser = new SysUser();
		queryUser.setId(user.getUserId());
		queryUser.setDelFlag(Constants.DELETE_NO);
		SysUser us = userMapper.selectOne(queryUser);
		if (Objects.isNull(us)) {
			throw new BusinessException("用户信息不存在");
		}
		String hash = encoder.encode(user.getPassword());
		queryUser.setPassword(hash);
		queryUser.setUpdater(securityUser.getRealName());
		queryUser.setUpdateBy(securityUser.getUserId());
		queryUser.setUpdateDate(new Date());
		return userMapper.updateByPrimaryKeySelective(queryUser);
	}


}
